package ca.etsmtl.log430.lab3.systemA;

import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.Vector;

/**
 * Filter for sorting projects by their state attribute
 * @author ah95800
 *
 */
public class SortFilter extends Thread {
	
	// Declarations

	// Create local pipes to that will connect to upstream filters
	PipedReader inputPipe = new PipedReader();

	// Create local pipes to that will connect to downstream filter
	PipedWriter outputPipe = new PipedWriter();

	public SortFilter(PipedWriter InputPipe, PipedWriter OutputPipe) {
		try {
			// Connect InputPipes to upstream filters
			this.inputPipe.connect(InputPipe);
			
			System.out.println("SortFilter:: connected to upstream filters.");
		} catch (Exception Error) {
			System.out.println("SortFilter:: Error connecting input pipes.");
		} // try/catch

		try {
			// Connect outputPipe to downstream filter
			this.outputPipe = OutputPipe;
			System.out.println("SortFilter:: connected to downstream filter.");
		} catch (Exception Error) {
			System.out.println("SortFilter:: Error connecting output pipe.");
		} // catch

	} // Constructor
	
	// This is the method that is called when the thread is started
	public void run() {
		// Declarations

		// Needs to be an array for easy conversion to string
		char[] characterValue1 = new char[1];

		boolean done = false; // Indicates when you are done
		// reading on input pipe
		int integerCharacter1; // integer value read from pipe
		String lineOfText = ""; // line of text from input pipe
		boolean write1 = false; // line of text to write to output
		Vector<String> projects = new Vector<String>();
		
		try
		{
			while (!done) {
				// Read input pipe
				integerCharacter1 = inputPipe.read();
				characterValue1[0] = (char) integerCharacter1;

				if (integerCharacter1 == -1) // input pipe is closed
				{
					done = true;
					System.out.println("SortFilter:: input pipe closed.");
					try {
						inputPipe.close();
					} catch (Exception Error) {
						System.out
								.println("SortFilter:: Error closing input pipe.");
					} // try/catch
				} else {
					if (integerCharacter1 == '\n') // end of line
					{
						System.out.println("SortFilter:: Received: "
								+ lineOfText + " on input pipe.");
						write1 = true;
					} else {
						lineOfText += new String(characterValue1);
					} // if
				} // if ( IntegerCharacter1 == -1 )
	
				if (write1) {
					// Add LineOfText1 to temporary string array,
					// increment arrayindex and reset Write1 to false.
					write1 = false;
					projects.add(lineOfText);
					lineOfText = "";
				} // if
	
			} // while (!Done1)
		} catch (Exception error) {

			System.out.println("SortFilter:: Interrupted.");

		} // try/catch
		
		// At this point, we have all lines of text in tmpArray.
		// Sort the projects by 'state'
		sortProjects(projects);
		
		// Write the sorted results to the output pipe
		try
		{
			for (String line : projects)
			{
				System.out.println("SortFilter:: Sending "
						+ line + " to output pipe.");
				line += "\n";
				outputPipe.write(line, 0, line.length());
				outputPipe.flush();
			}
		} catch (Exception IOError) {
			System.out.println("SortFilter:: Write Error.");
		} // try/catch
		
		// Close the output pipe
		try {
			System.out.println("SortFilter:: output pipe closed.");
			outputPipe.close();
		} catch (Exception Error) {
			System.out.println("SortFilter:: Error closing pipes");
		} // try/catch
	}
	
	/**
	 * Uses bubble sort to sort projects out by 'state'
	 * @param projects
	 */
	void sortProjects(Vector<String> projects)
	{
		int i;
		boolean done = false;
		String tmp;
		
		while (!done)
		{
			i = 0;
			done = true;
			
			while (i < projects.size() - 1)
			{
				if (new Project(projects.get(i).split(" ")).compareTo(new Project(projects.get(i + 1).split(" "))) > 0)
				{
					// Swapping
					tmp = projects.get(i);
					projects.set(i, projects.get(i + 1));
					projects.set(i + 1, tmp);
					
					done = false;
				}
				i++;
			}
		}
	}
}
